###############################################################################
## Tucan Project
##
## Copyright (C) 2008-2011 Elie Melois eliemelois@gmail.com
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
###############################################################################

import os
import time
from datetime import datetime

from google.appengine.api import users
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
from django.utils import simplejson as json
import logging

services = None

def delta_date(time=False):
	"""
	From : http://goo.gl/om6Ns
	"""
	now = datetime.now()
	if type(time) is int:
		diff = now - datetime.fromtimestamp(time)
	elif isinstance(time,datetime):
		diff = now - time 
	elif not time:
		diff = now - now
	second_diff = diff.seconds
	day_diff = diff.days

	if day_diff < 0:
		return ''

	if day_diff == 0:
		if second_diff < 10:
			return "just now"
		if second_diff < 60:
			return str(second_diff) + " seconds ago"
		if second_diff < 120:
			return  "a minute ago"
		if second_diff < 3600:
			return str( second_diff / 60 ) + " minutes ago"
		if second_diff < 7200:
			return "an hour ago"
		if second_diff < 86400:
			return str( second_diff / 3600 ) + " hours ago"
	if day_diff == 1:
		return "Yesterday"
	if day_diff < 7:
		return str(day_diff) + " days ago"
	if day_diff < 31:
		return str(day_diff/7) + " weeks ago"
	if day_diff < 365:
		return str(day_diff/30) + " months ago"
	return str(day_diff/365) + " years ago"

class Service(db.Model):
	name = db.StringProperty()
	update = db.StringProperty()
	plugins = db.ListProperty(db.Key)

class Plugin(db.Model):
	name = db.StringProperty()
	tester = db.UserProperty()
	success = db.BooleanProperty()
	error_message = db.TextProperty()
	last_test = db.DateTimeProperty(auto_now=True)

class Tester(db.Model):
	user = db.UserProperty()
	name = db.StringProperty()
	
class Tests(webapp.RequestHandler):
	
	def get(self):
		#t = Tester()
		#t.name = "Elie Melois"
		#t.user = users.get_current_user()
		#t.put()
		global services
		user = users.get_current_user()
		if user:
			if services:
				self.save_tests()
		else:
			self.redirect(users.create_login_url(self.request.uri))

	def post(self):
		global services
		user = users.get_current_user()
		if user:
			self.save_tests()
		else:
			services = json.loads(self.request.get('results'))
			self.redirect(users.create_login_url(self.request.uri))

	def save_tests(self):
		global services
		if not services:
			services = json.loads(self.request.get('results'))
		user = users.get_current_user()
		q = Tester.all()
		q.filter("user =",user)
		if q.get():
			for service in services:
				q = Service.all()
				q.filter("name =",service["name"])
				s = q.get()
				if not s:
					s = Service()
				s.name = service["name"]
				s.update = str(service["update"])
				for plugin in service["plugins"]:
					q = Plugin.all()
					q.filter("name =",plugin[0])
					p = q.get()
					new = False
					if not p:
						p = Plugin()
						new = True
					p.name = plugin[0]
					p.success = plugin[1]
					error = ""
					for test in plugin[2]:
						error += "%s : %s\n\n" % (test[0], test[1])
					p.error_message = error
					p.tester = user
					p.put()
					if new:
						s.plugins.append(p.key())
				s.put()
		services = None

class Dashboard(webapp.RequestHandler):

	def get(self):
		q = Service.all()
		services = []
		for service in q.run():
			tmp_service = {'name':service.name.capitalize(),'plugins':None,'most_recent':datetime(1970,1,1)}
			plugins = []
			for key in service.plugins:
				plugin = Plugin().get(key)
				tmp_plugin = {'name':'','success':'','last_test':''}
				plugin_names = {
						'Anonymous':'Anonymous Download',
						'Premium':'Premium Download',
						'AnonymousUpload':'Anonymous Upload',
						'PremiumUpload':'Premium Upload'
				}
				tmp_plugin["name"] = plugin_names[plugin.name.split("Test")[1]]
				tmp_plugin["last_test_display"] = delta_date(plugin.last_test)
				tmp_plugin["last_test"] = plugin.last_test
				tmp_plugin["success"] = "Correct" if plugin.success else "Failed"
				if plugin.last_test > tmp_service["most_recent"]:
					tmp_service["most_recent"] = plugin.last_test
				plugins.append(tmp_plugin)
			plugins = sorted(plugins, key=lambda plugin: plugin['last_test'], reverse=True)
			tmp_service["plugins"] = plugins
			services.append(tmp_service)
		services = sorted(services, key=lambda service: service['most_recent'], reverse=True)
		template_values = {
				'services': services
		}
		path = os.path.join(os.path.dirname(__file__), 'dashboard.html')
		self.response.out.write(template.render(path, template_values))


application = webapp.WSGIApplication([('/tests', Tests),('/dashboard',Dashboard)],debug=True)


def main():
	logging.getLogger().setLevel(logging.DEBUG)
	run_wsgi_app(application)

if __name__ == '__main__':
	main()
